import 'package:sqflite/sqflite.dart';
import '../models/emotion_record.dart';
import '../models/analytics_models.dart';
import '../models/statistics_summary.dart' as stats;
import '../services/database_service.dart';
import 'emotion_repository.dart';

/// 情绪记录数据仓库实现
/// Emotion record repository implementation
class EmotionRepositoryImpl implements EmotionRepository {
  final DatabaseService _databaseService = DatabaseService();

  @override
  Future<List<EmotionRecord>> getAllRecords() async {
    final db = await _databaseService.database;
    final List<Map<String, dynamic>> maps = await db.query(
      'emotion_records',
      orderBy: 'created_at DESC',
    );
    
    return List.generate(maps.length, (i) {
      return EmotionRecord.fromJson(maps[i]);
    });
  }

  @override
  Future<List<EmotionRecord>> getRecordsByDateRange({
    required DateTime startDate,
    required DateTime endDate,
  }) async {
    final db = await _databaseService.database;
    final List<Map<String, dynamic>> maps = await db.query(
      'emotion_records',
      where: 'created_at >= ? AND created_at <= ?',
      whereArgs: [startDate.toIso8601String(), endDate.toIso8601String()],
      orderBy: 'created_at DESC',
    );
    
    return List.generate(maps.length, (i) {
      return EmotionRecord.fromJson(maps[i]);
    });
  }

  @override
  Future<EmotionRecord?> getRecordById(String id) async {
    final db = await _databaseService.database;
    final List<Map<String, dynamic>> maps = await db.query(
      'emotion_records',
      where: 'id = ?',
      whereArgs: [id],
      limit: 1,
    );
    
    if (maps.isNotEmpty) {
      return EmotionRecord.fromJson(maps.first);
    }
    return null;
  }

  @override
  Future<List<EmotionRecord>> getTodayRecords() async {
    final now = DateTime.now();
    final startOfDay = DateTime(now.year, now.month, now.day);
    final endOfDay = startOfDay.add(const Duration(days: 1));
    
    return await getRecordsByDateRange(
      startDate: startOfDay,
      endDate: endOfDay,
    );
  }

  @override
  Future<List<EmotionRecord>> getRecentRecords({int limit = 10}) async {
    final db = await _databaseService.database;
    final List<Map<String, dynamic>> maps = await db.query(
      'emotion_records',
      orderBy: 'created_at DESC',
      limit: limit,
    );
    
    return maps.map((map) => EmotionRecord.fromJson(map)).toList();
  }

  @override
  Future<String> insertRecord(EmotionRecord record) async {
    final db = await _databaseService.database;
    await db.insert(
      'emotion_records',
      record.toJson(),
      conflictAlgorithm: ConflictAlgorithm.replace,
    );
    return record.id;
  }

  @override
  Future<void> updateRecord(EmotionRecord record) async {
    final db = await _databaseService.database;
    await db.update(
      'emotion_records',
      record.toJson(),
      where: 'id = ?',
      whereArgs: [record.id],
    );
  }

  @override
  Future<void> deleteRecord(String id) async {
    final db = await _databaseService.database;
    await db.delete(
      'emotion_records',
      where: 'id = ?',
      whereArgs: [id],
    );
  }

  @override
  Future<void> deleteRecords(List<String> ids) async {
    final db = await _databaseService.database;
    final batch = db.batch();
    
    for (final id in ids) {
      batch.delete(
        'emotion_records',
        where: 'id = ?',
        whereArgs: [id],
      );
    }
    
    await batch.commit();
  }

  @override
  Future<List<EmotionTrend>> getEmotionTrends({
    required DateRange dateRange,
  }) async {
    final db = await _databaseService.database;
    
    // 按日期分组统计情绪数据
    // Group emotion data by date
    final List<Map<String, dynamic>> maps = await db.rawQuery('''
      SELECT 
        DATE(created_at) as date,
        emotion_type,
        AVG(emotion_intensity) as avg_intensity,
        COUNT(*) as count
      FROM emotion_records 
      WHERE created_at >= ? AND created_at <= ?
      GROUP BY DATE(created_at), emotion_type
      ORDER BY date ASC
    ''', [dateRange.startDate.toIso8601String(), dateRange.endDate.toIso8601String()]);
    
    final Map<String, List<Map<String, dynamic>>> groupedByDate = {};
    
    for (final map in maps) {
      final date = map['date'] as String;
      if (!groupedByDate.containsKey(date)) {
        groupedByDate[date] = [];
      }
      groupedByDate[date]!.add(map);
    }
    
    return groupedByDate.entries.map((entry) {
      final date = DateTime.parse(entry.key);
      final emotions = entry.value;
      
      // 计算当天的平均情绪强度
      // Calculate average emotion intensity for the day
      double totalIntensity = 0;
      int totalCount = 0;
      
      for (final emotion in emotions) {
        final intensity = emotion['avg_intensity'] as double;
        final count = emotion['count'] as int;
        totalIntensity += intensity * count;
        totalCount += count;
      }
      
      final avgIntensity = totalCount > 0 ? totalIntensity / totalCount : 0.0;
      
      return EmotionTrend(
        date: date,
        emotionType: EmotionType.calm, // 默认情绪类型，实际应用中可能需要计算主要情绪类型
        averageIntensity: avgIntensity,
        recordCount: totalCount,
      );
    }).toList();
  }

  @override
  Future<List<EmotionDistribution>> getEmotionDistribution({
    required DateRange dateRange,
  }) async {
    final db = await _databaseService.database;
    
    final List<Map<String, dynamic>> maps = await db.rawQuery('''
      SELECT 
        emotion_type,
        COUNT(*) as count,
        AVG(emotion_intensity) as avg_intensity
      FROM emotion_records 
      WHERE created_at >= ? AND created_at <= ?
      GROUP BY emotion_type
      ORDER BY count DESC
    ''', [dateRange.startDate.toIso8601String(), dateRange.endDate.toIso8601String()]);
    
    final totalCount = maps.fold<int>(0, (sum, map) => sum + (map['count'] as int));
    
    return maps.map((map) {
      final emotionType = EmotionType.values.firstWhere(
        (e) => e.name == map['emotion_type'],
        orElse: () => EmotionType.calm,
      );
      
      final count = map['count'] as int;
      final percentage = totalCount > 0 ? (count / totalCount) * 100 : 0.0;
      
      return EmotionDistribution(
        emotionType: emotionType,
        count: count,
        percentage: percentage,
      );
    }).toList();
  }

  @override
  Future<List<WordFrequency>> getWordFrequencies({
    required DateRange dateRange,
    int limit = 50,
  }) async {
    final db = await _databaseService.database;
    
    final List<Map<String, dynamic>> maps = await db.query(
      'emotion_records',
      columns: ['diary_content'],
      where: 'created_at >= ? AND created_at <= ? AND diary_content IS NOT NULL',
      whereArgs: [dateRange.startDate.toIso8601String(), dateRange.endDate.toIso8601String()],
    );
    
    // 简单的词频统计（实际项目中可能需要更复杂的中文分词）
    // Simple word frequency counting (may need more complex Chinese word segmentation in real projects)
    final Map<String, int> wordCount = {};
    
    for (final map in maps) {
      final content = map['diary_content'] as String?;
      if (content != null && content.isNotEmpty) {
        // 简单按字符分割（实际应用中建议使用专业的中文分词库）
        // Simple character splitting (recommend using professional Chinese word segmentation library in real applications)
        final words = content.split(RegExp(r'[\s，。！？；：、]')).where((word) => word.length > 1).toList();
        
        for (final word in words) {
          wordCount[word] = (wordCount[word] ?? 0) + 1;
        }
      }
    }
    
    // 按频率排序并限制数量
    // Sort by frequency and limit count
    final sortedWords = wordCount.entries.toList()
      ..sort((a, b) => b.value.compareTo(a.value));
    
    return sortedWords.take(limit).map((entry) {
      // 计算权重（基于频率的归一化值）
      // Calculate weight (normalized value based on frequency)
      final maxFrequency = sortedWords.isNotEmpty ? sortedWords.first.value : 1;
      final weight = entry.value / maxFrequency;
      
      return WordFrequency(
        word: entry.key,
        frequency: entry.value,
        weight: weight,
      );
    }).toList();
  }

  @override
  Future<stats.StatisticsSummary> getStatisticsSummary() async {
    final db = await _databaseService.database;
    
    // 获取总记录数
    // Get total record count
    final totalCountResult = await db.rawQuery('SELECT COUNT(*) as count FROM emotion_records');
    final totalRecords = totalCountResult.first['count'] as int;
    
    // 获取本周记录数
    // Get this week's record count
    final now = DateTime.now();
    final startOfWeek = now.subtract(Duration(days: now.weekday - 1));
    final endOfWeek = startOfWeek.add(const Duration(days: 7));
    
    final weekCountResult = await db.rawQuery(
      'SELECT COUNT(*) as count FROM emotion_records WHERE created_at >= ? AND created_at < ?',
      [startOfWeek.toIso8601String(), endOfWeek.toIso8601String()],
    );
    final weekRecords = weekCountResult.first['count'] as int;
    
    // 获取平均情绪强度
    // Get average emotion intensity
    final avgIntensityResult = await db.rawQuery('SELECT AVG(emotion_intensity) as avg FROM emotion_records');
    final avgIntensity = (avgIntensityResult.first['avg'] as double?) ?? 0.0;
    
    // 获取最常见的情绪类型
    // Get most common emotion type
    final mostCommonResult = await db.rawQuery('''
      SELECT emotion_type, COUNT(*) as count 
      FROM emotion_records 
      GROUP BY emotion_type 
      ORDER BY count DESC 
      LIMIT 1
    ''');
    
    EmotionType? mostCommonEmotion;
    if (mostCommonResult.isNotEmpty) {
      final emotionTypeName = mostCommonResult.first['emotion_type'] as String;
      mostCommonEmotion = EmotionType.values.firstWhere(
        (e) => e.name == emotionTypeName,
        orElse: () => EmotionType.calm,
      );
    }
    

    
    return stats.StatisticsSummary(
      totalRecords: totalRecords,
      weekRecords: weekRecords,
      averageIntensity: avgIntensity,
      mostCommonEmotion: mostCommonEmotion?.value ?? '',
      mostCommonEmotionCount: mostCommonResult.isNotEmpty ? mostCommonResult.first['count'] as int : 0,
      emotionDistribution: await _getEmotionDistribution(),
      weeklyTrend: await _getWeeklyTrend(startOfWeek, endOfWeek),
      startDate: startOfWeek,
      endDate: endOfWeek,
    );
  }

  @override
  Future<List<EmotionRecord>> searchRecords({
    required String keyword,
    EmotionType? emotionType,
    DateRange? dateRange,
  }) async {
    final db = await _databaseService.database;
    
    String whereClause = 'diary_content LIKE ?';
    List<dynamic> whereArgs = ['%$keyword%'];
    
    if (emotionType != null) {
      whereClause += ' AND emotion_type = ?';
      whereArgs.add(emotionType.name);
    }
    
    if (dateRange != null) {
      whereClause += ' AND created_at >= ? AND created_at <= ?';
      whereArgs.add(dateRange.startDate.toIso8601String());
      whereArgs.add(dateRange.endDate.toIso8601String());
    }
    
    final List<Map<String, dynamic>> maps = await db.query(
      'emotion_records',
      where: whereClause,
      whereArgs: whereArgs,
      orderBy: 'created_at DESC',
    );
    
    return List.generate(maps.length, (i) {
      return EmotionRecord.fromJson(maps[i]);
    });
  }

  @override
  Future<int> getRecordCount() async {
    final db = await _databaseService.database;
    final result = await db.rawQuery('SELECT COUNT(*) as count FROM emotion_records');
    return result.first['count'] as int;
  }

  @override
  Future<List<EmotionRecord>> getRecordsPaginated({
    required int page,
    required int pageSize,
  }) async {
    final db = await _databaseService.database;
    
    final offset = page * pageSize;
    
    final List<Map<String, dynamic>> maps = await db.query(
      'emotion_records',
      orderBy: 'created_at DESC',
      limit: pageSize,
      offset: offset,
    );
    
    return List.generate(maps.length, (i) {
      return EmotionRecord.fromJson(maps[i]);
    });
  }

  @override
  Future<bool> hasTodayRecords() async {
    final todayRecords = await getTodayRecords();
    return todayRecords.isNotEmpty;
  }

  @override
  Future<int> getConsecutiveRecordingDays() async {
    final db = await _databaseService.database;
    
    // 获取所有有记录的日期
    // Get all dates with records
    final List<Map<String, dynamic>> maps = await db.rawQuery('''
      SELECT DISTINCT DATE(created_at) as date 
      FROM emotion_records 
      ORDER BY date DESC
    ''');
    
    if (maps.isEmpty) return 0;
    
    int consecutiveDays = 0;
    DateTime? previousDate;
    
    for (final map in maps) {
      final currentDate = DateTime.parse(map['date'] as String);
      
      if (previousDate == null) {
        // 第一个日期
        // First date
        consecutiveDays = 1;
        previousDate = currentDate;
      } else {
        // 检查是否连续
        // Check if consecutive
        final difference = previousDate.difference(currentDate).inDays;
        if (difference == 1) {
          consecutiveDays++;
          previousDate = currentDate;
        } else {
          // 不连续，停止计算
          // Not consecutive, stop counting
          break;
        }
      }
    }
    
    return consecutiveDays;
  }

  /// 获取情绪分布统计
  /// Get emotion distribution statistics
  Future<Map<String, int>> _getEmotionDistribution() async {
    final db = await _databaseService.database;
    
    final result = await db.rawQuery('''
      SELECT emotion_type, COUNT(*) as count 
      FROM emotion_records 
      GROUP BY emotion_type
    ''');
    
    final Map<String, int> distribution = {};
    for (final row in result) {
      final emotionTypeName = row['emotion_type'] as String;
      final emotionType = EmotionType.values.firstWhere(
        (e) => e.name == emotionTypeName,
        orElse: () => EmotionType.calm,
      );
      distribution[emotionType.value] = row['count'] as int;
    }
    
    return distribution;
  }
  
  /// 获取本周情绪趋势
  /// Get weekly emotion trend
  Future<List<stats.DailyEmotionSummary>> _getWeeklyTrend(DateTime startOfWeek, DateTime endOfWeek) async {
    final db = await _databaseService.database;
    
    final result = await db.rawQuery('''
      SELECT 
        DATE(created_at) as date,
        COUNT(*) as record_count,
        AVG(emotion_intensity) as avg_intensity,
        emotion_type
      FROM emotion_records 
      WHERE created_at >= ? AND created_at < ?
      GROUP BY DATE(created_at), emotion_type
      ORDER BY date, COUNT(*) DESC
    ''', [startOfWeek.toIso8601String(), endOfWeek.toIso8601String()]);
    
    final Map<String, stats.DailyEmotionSummary> dailySummaries = {};
    
    for (final row in result) {
      final dateStr = row['date'] as String;
      final date = DateTime.parse(dateStr);
      final recordCount = row['record_count'] as int;
      final avgIntensity = (row['avg_intensity'] as double?) ?? 0.0;
      final emotionTypeName = row['emotion_type'] as String;
      
      final emotionType = EmotionType.values.firstWhere(
        (e) => e.name == emotionTypeName,
        orElse: () => EmotionType.calm,
      );
      
      if (!dailySummaries.containsKey(dateStr)) {
        dailySummaries[dateStr] = stats.DailyEmotionSummary(
          date: date,
          recordCount: recordCount,
          averageIntensity: avgIntensity,
          primaryEmotion: emotionType.value,
        );
      }
    }
    
    return dailySummaries.values.toList()..sort((a, b) => a.date.compareTo(b.date));
  }

  @override
  Future<Map<String, dynamic>> exportAllData() async {
    final records = await getAllRecords();
    
    return {
      'emotion_records': records.map((record) => record.toJson()).toList(),
      'export_date': DateTime.now().toIso8601String(),
      'version': '1.0',
    };
  }

  @override
  Future<void> clearAllData() async {
    final db = await _databaseService.database;
    await db.delete('emotion_records');
  }
}
